package com.newtribe.security;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Vector;

import javax.security.auth.x500.X500Principal;

import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERConstructedSet;
import org.bouncycastle.asn1.DEREncodableVector;
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DERInputStream;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
import org.bouncycastle.asn1.x509.AccessDescription;
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.CRLDistPoint;
import org.bouncycastle.asn1.x509.CertificatePolicies;
import org.bouncycastle.asn1.x509.DistributionPoint;
import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.asn1.x509.X509Name;
import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.bouncycastle.jce.X509KeyUsage;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;

import sun.security.pkcs.PKCS10;
import sun.security.x509.X500Name;
import sun.security.x509.X500Signer;

public class CertSignature {
  public CertSignature() {
  }

  // Creates a PKCS#10 cert signing request, corresponding to the     * keys (and name) associated with a given alias.     */
 public static void doCertReq() throws
     Exception {
	 
//	    KeyStore keystore =KeyStore.getInstance("jks") ;
//
//	    InputStream in =new FileInputStream ("D:/ca/cross-cert/ca1/gfa_keystore.jks") ;
//	    keystore.load(in ,"111111".toCharArray());
	    
//   PrivateKey privKey = (PrivateKey)keystore.getKey("server", "111111".toCharArray()) ;
//
//   
//   Certificate cert  =keystore.getCertificate("test") ;
//
//   if (cert == null) {
//     throw new Exception( " has no public key (certificate)");
//   }
    KeyPair ca1Rootkey=readKeyPair("D:/ca/cross-cert/key/ca1Rootkey.key") ;
    PrivateKey privKey =ca1Rootkey.getPrivate();
    
    CertificateFactory certFactory = CertificateFactory.getInstance("X.509") ;
    InputStream parent =new FileInputStream("D:/ca/cross-cert/ca1/gfa_root.cer") ;
     X509Certificate cert =  (X509Certificate)certFactory.generateCertificate(parent) ;
     parent.close();
	    
   PKCS10 request = new PKCS10(cert.getPublicKey());
  
   // Construct an X500Signer object, so that we can sign the request    if (sigAlgName == null) {        // If no signature algorithm was specified at the command line,        // we choose one that is compatible with the selected private key        String keyAlgName = privKey.getAlgorithm();        if (keyAlgName.equalsIgnoreCase("DSA")           || keyAlgName.equalsIgnoreCase("DSS")) {        sigAlgName = "SHA1WithDSA";        } else if (keyAlgName.equalsIgnoreCase("RSA")) {        sigAlgName = "MD5WithRSA";        } else {        throw new Exception("Cannot derive signature algorithm");        }    }

   Signature signature = Signature.getInstance("SHA1withRSA");
   signature.initSign(privKey);
   X500Name subject = new X500Name( ( (X509Certificate) cert).getSubjectDN().
                                   toString());
   X500Signer signer = new X500Signer(signature, subject);

   // Sign the request and base-64 encode it
   request.encodeAndSign(signer);
  // request.print(System.out);
   
   
   ASN1EncodableVector v = new ASN1EncodableVector();
   DERConstructedSet s1 = new DERConstructedSet(v);

  PKCS10CertificationRequest req = new PKCS10CertificationRequest("SHA1withRSA", new X509Name(ca1rootdn), 
		  cert.getPublicKey(), s1, privKey);
  String recert=new String(Base64.encode(req.getEncoded()));
  FileWriter fos =new FileWriter("D:/ca/cross-cert/gfa_p10-request.cer");
  fos.write(recert) ;
  fos.close();
  
   System.out.println("================\n");
 }
 
 public static void writePEM(Object object,String filename)throws Exception {
	 FileWriter f =new FileWriter(filename);
	 PEMWriter writer =new PEMWriter(f) ;
	 writer.writeObject(object);
	 writer.close();
	 f.close();
 }
 
 public static void processP10 (String p10File) throws Exception{
	 byte[] req = null;

     // Read PEM encoded certificate
     System.out.println("Reading p10 request certificate ...");
     try {
        File f = new File(p10File);
        FileInputStream fis = new FileInputStream(f);
        req = new byte[(int)f.length()];
        fis.read(req);
        fis.close();
     } catch(Exception e) { System.out.println(e); }

     // Create PKCS#10 object
     byte[] der = Base64.decode(req);
     PKCS10CertificationRequest pkcr = new PKCS10CertificationRequest(der);
     CertificationRequestInfo cri = pkcr.getCertificationRequestInfo();

     System.out.println("CSR subject is ...");
     System.out.println(cri.getSubject().toString());
     System.out.println();

     // Read CA cert from KeyStore
     System.out.println("Reading CA signer  certificate ...");
     PrivateKey caPrivKey = null;
     X509Certificate caCert = null;
     try {
   	  
  	   KeyStore keystore = KeyStore.getInstance("jks");
  	    InputStream in = new FileInputStream("D:/ca/p10test/test.jks");
  	    keystore.load(in, "111111".toCharArray());
  	    
        caPrivKey = (PrivateKey)keystore.getKey("root", "111111".toCharArray());
        caCert = (X509Certificate)keystore.getCertificate("root");
     } catch(Exception e) { System.out.println(e); }

     // Sign the certificate
     System.out.println("Signing certificate ...");
     X509Certificate genCert = null;
     try {
        X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
        v3CertGen.reset();  
        v3CertGen.setSubjectDN(cri.getSubject());
        v3CertGen.setPublicKey(pkcr.getPublicKey());
        v3CertGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
        v3CertGen.setSignatureAlgorithm(caCert.getSigAlgName());
//        v3CertGen.setIssuerDN(new
//        org.bouncycastle.asn1.x509.X509Name((caCert.getSubjectDN().getName())));
        
        X500Principal principal =caCert.getSubjectX500Principal();
        v3CertGen.setIssuerDN(principal);
        // Certificate valid from today ...
        v3CertGen.setNotBefore(new java.util.Date(System.currentTimeMillis()));
        // ... until one year from today
        v3CertGen.setNotAfter(new java.util.Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365)));
        
        genCert = v3CertGen.generateX509Certificate(caPrivKey);
     } catch(Exception e) { System.out.println(e); }

     // Output signed certificate in PEM format
     System.out.println(genCert.toString());
     System.out.println("-----BEGIN CERTIFICATE-----");
     try {
        System.out.println(new String(Base64.encode(genCert.getEncoded())));
        writeFile("D:/ca/p10test/response.cer" ,genCert) ;
     } catch(Exception e) { System.out.println(e); }
     System.out.println("-----END CERTIFICATE-----");

  }
 
 public static KeyPair readKeyPair (String file) throws Exception {
	 
		 java.io.ObjectInputStream out = new java.io.ObjectInputStream(new
		            java.io.FileInputStream(file));
		        
		     KeyPair kp =(KeyPair)out.readObject();
		        out.close();
		        return kp ;
	
 }
 
 public static KeyPair readKeyPairFromStore(String file) throws Exception{
	    KeyStore keystore =KeyStore.getInstance("jks") ;

	    InputStream in =new FileInputStream (file) ;
	    keystore.load(in ,"123456".toCharArray());
        in.close();
        
        PrivateKey priKey = (PrivateKey) keystore.getKey("rsakeytwo","123456".toCharArray()) ;
	    PublicKey pubKey =keystore.getCertificate("rsakeytwo").getPublicKey();
	    return new KeyPair(pubKey, priKey);
	    
 }
 public static String readDn(String file)throws Exception {
	    CertificateFactory certFactory = CertificateFactory.getInstance("X.509") ;
	    InputStream parent =new FileInputStream(file) ;
	     X509Certificate cert =  (X509Certificate)certFactory.generateCertificate(parent) ;
	     parent.close();
	     return   cert.getSubjectDN().toString();
	 
 }
 
 public static X509Certificate readCertificate(String file)throws Exception {
	    CertificateFactory certFactory = CertificateFactory.getInstance("X.509") ;
	    InputStream parent =new FileInputStream(file) ;
	     X509Certificate cert =  (X509Certificate)certFactory.generateCertificate(parent) ;
	     parent.close();
	     return   cert;
	 
}
 
 public static void writeKeyPair(String file ,KeyPair kp)throws Exception {
	 
//	 File fl =new File(file) ;
//	 if (fl.exists()==false)
//		 fl.mkdir();
	 java.io.ObjectOutputStream out = new java.io.ObjectOutputStream(new
	            java.io.FileOutputStream(file));
	        out.writeObject(kp);
	        out.close();
 }
 
 
 static String hk_rootdn = "C=HK, O=DIGI-SIGN CERTIFICATION SERVICES LIMITED,OU=BRN 31346952-000,CN=ID-CERT ROOT CA CERT 1";

 public static void initCA2() throws Exception{
	
	 
	    
	 //ca2 keypair    
	   // KeyPair ca2Rootkey=keyPairGen.genKeyPair();
	    KeyPair ca2Rootkey=readKeyPair("D:/ca/cross-cert/key/ca2Rootkey.key") ;
	   // KeyPair bridgerootkey=readKeyPair("D:/ca/cross-cert/key/bridgerootkey.key") ;
	    KeyPair bridgerootkey=readKeyPairFromStore("D:/ca/cross-cert/key/keystore.key") ;
	    
	    KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("RSA");
	    keyPairGen.initialize(1024);
	    KeyPair ca2Userkey=keyPairGen.genKeyPair();

	    
	    //sign sert use keypair above .
	    
		   System.out.println("========================== sign cert ======================");

	    //generate root self sign certificate 
	    
	    X509Certificate ca2RootCert =signCert(hk_rootdn,hk_rootdn,ca2Rootkey.getPrivate(),ca2Rootkey.getPublic()
	    		,ca2Rootkey.getPublic(),0,10,false);
	    writeFile("D:/ca/cross-cert/ca2/hk_root.cer",ca2RootCert) ;

	    
	    //generate ca2 user certificate 
	    String userdn = "C=hk, O=tradelink,E=service@tradelink.com,OU=tradelink,CN=hk_asia_sdc91";
	    X509Certificate ca2UserCert =signCert(userdn,hk_rootdn,ca2Rootkey.getPrivate(),
	    		ca2Userkey.getPublic(),ca2Rootkey.getPublic(),2,1,false);
	    writeFile("D:/ca/cross-cert/ca2/hk_user1.cer",ca2UserCert) ;

	 
	    //generate ca2 for bridge cert.
	  //  String ca2ForBridgeDn = "C=cn, O=gfa,L=bj,ST=bj,E=root@ec.com.cn,OU=software center,CN=ciecc crosscert center";
	
	    String ca2ForBridgeDn = readDn("D:/ca/cross-cert/key/crossca.cer");
	    X509Certificate ca2ForBridgeCert =signCert(ca2ForBridgeDn,hk_rootdn,ca2Rootkey.getPrivate(),
	    		bridgerootkey.getPublic(),ca2Rootkey.getPublic(),1,1,false);
	    
	    writeFile("D:/ca/cross-cert/ca2/hk_to_Bridge.cer",ca2ForBridgeCert);
	    
		   System.out.println("========================== write keystore ======================");

	    
	    //store to keystore file 
	     String keystoreFile ="D:/ca/cross-cert/ca2/hk-keystore.jks" ;
		  KeyStore keystore = KeyStore.getInstance("jks");
		  keystore.load(null) ;
		  
//		  keystore.setKeyEntry("ca2 root",ca2Rootkey.getPrivate(), "111111".toCharArray(), 
//				  new X509Certificate[]{ca2RootCert}) ;
		 
		  keystore.setCertificateEntry("root", ca2RootCert) ;
		  
		  keystore.setKeyEntry("user",ca2Userkey.getPrivate(), "111111".toCharArray(), 
				  new X509Certificate[]{ca2UserCert,ca2RootCert}) ;
		
		
		  keystore.store(new FileOutputStream(keystoreFile), "111111".toCharArray());
		  
		  
 }
 
 public static void initCA3() throws Exception{
		
	 
	    
	 //ca1  keypair 
	   System.out.println("========================== gen user keypair ======================");
	    KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("RSA");
	    keyPairGen.initialize(1024);
	        
	    KeyPair ca1Ope01key=readKeyPair("D:/ca/cross-cert/key/ca1Ope01key.key") ;
	    KeyPair ca1Userkey=keyPairGen.genKeyPair();
	 

	    X509Certificate ca1RootCert =readCertificate("D:\\ca\\cross-cert\\ca1\\gfa_root.cer");
	    X509Certificate ca1Ope01Cert=readCertificate("D:\\ca\\cross-cert\\ca1\\gfa_ope01.cer");

	    String subdn = "C=cn, O=gfa,L=bj,ST=bj,E=ope01@ec.com.cn,OU=ciecc,CN=operation ca02 for gfa trust network";
	    String userdn = "C=cn, O=gfa,L=bj,ST=bj,OU=ciecc,CN=211.88.12.87";
	    X509Certificate ca1UserCert =signCert(userdn,subdn,ca1Ope01key.getPrivate(),
	    		ca1Userkey.getPublic(),ca1Ope01key.getPublic(),2,1,true);
	   
	    writeFile("D:/ca/cross-cert/usern/user.cer",ca1UserCert) ;
	    
	   //


		   System.out.println("========================== write keystore ======================");

	    
	    //store to keystore file 
	     String keystoreFile ="D:/ca/cross-cert/usern/user-keystore.jks" ;
		  KeyStore keystore = KeyStore.getInstance("jks");
		  keystore.load(null) ;
		  /*
		  keystore.setKeyEntry("ca1 root",ca1Rootkey.getPrivate(), "111111".toCharArray(), 
				  new X509Certificate[]{ca1RootCert}) ;
		  
		  keystore.setKeyEntry("ope01",ca1Ope01key.getPrivate(), "111111".toCharArray(), 
				  new X509Certificate[]{ca1Ope01Cert ,ca1RootCert}) ;
				  */
		  
		  keystore.setCertificateEntry("root", ca1RootCert);
		  
		  keystore.setKeyEntry("server",ca1Userkey.getPrivate(), "111111".toCharArray(), 
				  new X509Certificate[]{ca1UserCert,ca1Ope01Cert}) ;
//		  keystore.setKeyEntry("user",ca1Userkey.getPrivate(), "111111".toCharArray(), 
//				  new X509Certificate[]{ca1UserCert}) ;

		  keystore.store(new FileOutputStream(keystoreFile), "111111".toCharArray());
		  
		  
 }
 
 public static void initKeyPair() throws Exception{
	 
	   System.out.println("========================== gen keypair ======================");
	    KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("RSA");
	    keyPairGen.initialize(1024);
	    KeyPair ca1Rootkey=keyPairGen.genKeyPair();
	    writeKeyPair("D:/ca/cross-cert/key/ca1Rootkey.key" ,ca1Rootkey) ;
	    
	    
	    KeyPair ca1Ope01key=keyPairGen.genKeyPair();
	    writeKeyPair("D:/ca/cross-cert/key/ca1Ope01key.key" ,ca1Ope01key) ;
//	    
//	    
	    KeyPair ca2Rootkey=keyPairGen.genKeyPair();
	    writeKeyPair("D:/ca/cross-cert/key/ca2Rootkey.key" ,ca2Rootkey) ;
//	    
//	    
	    KeyPair bridgerootkey=keyPairGen.genKeyPair();
	    writeKeyPair("D:/ca/cross-cert/key/bridgerootkey.key" ,bridgerootkey) ;
	    
	    
	    KeyPair ca3Rootkey=keyPairGen.genKeyPair();
	    writeKeyPair("D:/ca/cross-cert/key/ca3Rootkey.key" ,ca3Rootkey) ;
	    
	 
 }
 
 public static void initBridge() throws Exception{
		
	   System.out.println("========================== gen keypare ======================");
	
	 //bridge keypair

	   // KeyPair bridgerootkey=readKeyPair("D:/ca/cross-cert/key/bridgerootkey.key") ;
	    KeyPair bridgerootkey=readKeyPairFromStore("D:/ca/cross-cert/key/keystore.key") ;

	    
	    KeyPair ca1Rootkey=readKeyPair("D:/ca/cross-cert/key/ca1Rootkey.key") ;
	    KeyPair ca2Rootkey=readKeyPair("D:/ca/cross-cert/key/ca2Rootkey.key") ;


	    
	    KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("RSA");
	    keyPairGen.initialize(1024);
	    
	    //sign sert use keypair above .
	    
		   System.out.println("========================== sign cert ======================");

	    //generate root self sign certificate 
	    String rootdn = "C=cn" + ", O=gfa" + ",L=bj"
	    + ",ST=bj" + ",E=root@ec.com.cn"
	    + ",OU=software center" + ",CN=ciecc crosscert center";
	    X509Certificate bridgeRootCert =signCert(rootdn,rootdn,bridgerootkey.getPrivate(),bridgerootkey.getPublic()
	    		,bridgerootkey.getPublic(),0);
	    writeFile("D:/ca/cross-cert/bridgeRootCert.cer",bridgeRootCert) ;

	    
	    //generate bridge to ca1  certificate 
	    
	    String bridgeToCA1DN = "C=cn" + ", O=gfa" + ",L=bj"
	    + ",ST=bj" + ",E=root@ec.com.cn"
	    + ",OU=software center" + ",CN=ca-gfa root";
	    
	    X509Certificate bridgeToCA1Cert =signCert(bridgeToCA1DN,rootdn,bridgerootkey.getPrivate(),
	    		ca1Rootkey.getPublic(),bridgerootkey.getPublic(),1);
	    
	    writeFile("D:/ca/cross-cert/bridgeToCA1Cert.cer",bridgeToCA1Cert) ;

	    
	    //generate bridge to ca2  certificate 
	    
	    String bridgeToCA2DN = "C=cn" + ", O=gfa" + ",L=bj"
	    + ",ST=bj" + ",E=root@ec.com.cn"
	    + ",OU=software center" + ",CN=ca-hk root";
	    
	    X509Certificate bridgeToCA2Cert =signCert(bridgeToCA2DN,rootdn,bridgerootkey.getPrivate(),
	    		ca2Rootkey.getPublic(),bridgerootkey.getPublic(),1);
	    
	    writeFile("D:/ca/cross-cert/bridgeToCA2Cert.cer",bridgeToCA2Cert) ;

	   
		   System.out.println("========================== write keystore ======================");
	    //store to keystore file 
	     String keystoreFile ="D:/ca/cross-cert/bridge-auto.jks" ;
		  KeyStore keystore = KeyStore.getInstance("jks");
		  keystore.load(null) ;
		  
		  keystore.setKeyEntry("bridge ca root",bridgerootkey.getPrivate(), "111111".toCharArray(), 
				  new X509Certificate[]{bridgeRootCert}) ;
		  
		  keystore.setCertificateEntry("bridgeToCA1", bridgeToCA1Cert) ;

		  keystore.setCertificateEntry("bridgeToCA2", bridgeToCA2Cert) ;
		
		  keystore.store(new FileOutputStream(keystoreFile), "111111".toCharArray());
		  
		  
}

 
    static String ca1rootdn = "C=cn,O=gfa,L=bj,ST=bj,E=root@ec.com.cn,OU=ciecc,CN=gfa root certificate";
    
 public static void initCA1() throws Exception {
	 
	 //ca1  keypair 
	   System.out.println("========================== gen user keypair ======================");
	    KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("RSA");
	    keyPairGen.initialize(1024);
	        
	    KeyPair ca1Rootkey=readKeyPair("D:/ca/cross-cert/key/ca1Rootkey.key") ;
	    KeyPair ca1Ope01key=readKeyPair("D:/ca/cross-cert/key/ca1Ope01key.key") ;
	    KeyPair ca1Userkey=keyPairGen.genKeyPair();
	   // KeyPair bridgerootkey=readKeyPair("D:/ca/cross-cert/key/bridgerootkey.key") ;

	    
	    //sign sert use keypair above .
	    
		   System.out.println("========================== sign cert ======================");

	    //generate root self sign certificate 

	    X509Certificate ca1RootCert =signCert(ca1rootdn,ca1rootdn,ca1Rootkey.getPrivate(),ca1Rootkey.getPublic()
	    		,ca1Rootkey.getPublic(),0,10,true);
	   // writeFile("D:/ca/cross-cert/ca1/gfa_root.cer",ca1RootCert) ;


	    //generate ope01 certificate 
	    String subdn = "C=cn, O=gfa,L=bj,ST=bj,E=ope01@ec.com.cn,OU=ciecc,CN=operation ca02 for gfa trust network";
	    X509Certificate ca1Ope01Cert =signCert(subdn,ca1rootdn,ca1Rootkey.getPrivate(),
	    		ca1Ope01key.getPublic(),ca1Rootkey.getPublic(),1,10,true);
	   
	    writeFile("D:/ca/cross-cert/ca1/gfa_ope01.cer",ca1Ope01Cert) ;
	    
	    
	    //generate ca1 user certificate 
	    String userdn = "C=cn, O=gfa,L=bj,ST=bj,OU=ciecc,CN=211.88.18.145";
	    X509Certificate ca1UserCert =signCert(userdn,subdn,ca1Ope01key.getPrivate(),
	    		ca1Userkey.getPublic(),ca1Ope01key.getPublic(),2,1,true);
	   
	    writeFile("D:/ca/cross-cert/ca1/gfa_user.cer",ca1UserCert) ;
	    
	    
	    //generate ca1 for bridge cert.
//	    
//	    String ca1ForBridgeDn = "C=cn" + ", O=gfa" + ",L=bj"
//	    + ",ST=bj" + ",E=root@ec.com.cn"
//	    + ",OU=software center" + ",CN=ciecc crosscert center";
	    
//	    X509Certificate ca1ForBridgeCert =signCert(ca1ForBridgeDn,rootdn,ca1Rootkey.getPrivate(),
//	    		bridgerootkey.getPublic(),ca1Rootkey.getPublic(),1);
//	    
//	    writeFile("D:/ca/cross-cert/ca1ForBridgeDn.cer",ca1ForBridgeCert);


		   System.out.println("========================== write keystore ======================");

	    
	    //store to keystore file 
	     String keystoreFile ="D:/ca/cross-cert/ca1/gfa-keystore.jks" ;
		  KeyStore keystore = KeyStore.getInstance("jks");
		  keystore.load(null) ;
		  /*
		  keystore.setKeyEntry("ca1 root",ca1Rootkey.getPrivate(), "111111".toCharArray(), 
				  new X509Certificate[]{ca1RootCert}) ;
		  
		  keystore.setKeyEntry("ope01",ca1Ope01key.getPrivate(), "111111".toCharArray(), 
				  new X509Certificate[]{ca1Ope01Cert ,ca1RootCert}) ;
				  */
		  
		  keystore.setCertificateEntry("root", ca1RootCert);
		  
		  keystore.setKeyEntry("server",ca1Userkey.getPrivate(), "111111".toCharArray(), 
				  new X509Certificate[]{ca1UserCert,ca1Ope01Cert}) ;
//		  keystore.setKeyEntry("user",ca1Userkey.getPrivate(), "111111".toCharArray(), 
//				  new X509Certificate[]{ca1UserCert}) ;

		  keystore.store(new FileOutputStream(keystoreFile), "111111".toCharArray());
		  
		 

 }
 
 public static void main(String[] args) throws Exception {
	 System.out.println(Long.MAX_VALUE);
	    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

	// initKeyPair();
	 //initBridge();
	 //初始化模拟国富安CA。
	initCA1();
	 
	 //模拟香港CA
	// initCA2();
	//initCA3();
	// doCertReq();
	 
	    
	   //把密钥存储为pem格式，和openssl 等进行集成
	    
	   /*
	    KeyStore keystore =KeyStore.getInstance("jks") ;

	    InputStream in =new FileInputStream ("D:/ca/cross-cert/ca1/gfa-keystore.jks") ;
	    keystore.load(in ,"111111".toCharArray());
        in.close();
        
        PrivateKey priKey = (PrivateKey) keystore.getKey("server","111111".toCharArray()) ;
        writePEM(priKey,"D:/ca/cross-cert/ca1/gfa_user_prikey.pem");
        
        */
	 
	
 }

 

  public static void main_1(String[] args) throws Exception {

	    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

	// doCertReq();
	  
//	  processP10("D:/ca/p10test/csr.csr");
//	  if(true)return ;
	  
	  
  //  signCert();
//     X509CertImpl cert =new X509CertImpl () ;
//    // cert.set();
//     X509CertInfo info =(X509CertInfo)cert.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); ;
//
//     Date begindate=new Date();
//    Date enddate=new Date(begindate.getTime()+3000*24*60*60*1000L);
//     CertificateValidity cv=new CertificateValidity(begindate,enddate);
//     info.set(X509CertInfo.VALIDITY,cv);
//     byte[] b =cert.getEncoded() ;
	  
	   KeyStore keystore = KeyStore.getInstance("jks");
	    InputStream in = new FileInputStream("D:/ca/cross-cert/ca1.jks");
	    keystore.load(in, "111111".toCharArray());
	    
	    X509Certificate userCert = (X509Certificate)keystore.getCertificate("gfa ca certificate");
	    PrivateKey userPrivateKey = (PrivateKey) keystore.getKey("gfa ca certificate","111111".toCharArray());
	    X509Certificate userCaroot = (X509Certificate)keystore.getCertificate("gfa ca certificate");
	    PublicKey userPubKey =userCaroot.getPublicKey();
	  
	    PrivateKey caPrivateKey = (PrivateKey) keystore.getKey("root","111111".toCharArray());
	    X509Certificate caroot = (X509Certificate)keystore.getCertificate("root");
	    PublicKey caPubKey =caroot.getPublicKey();
	    
	    //generate root 
	    String rootdn = "C=cn" + ", O=newtribe" + ",L=QinHuangDao"
	    + ",ST=HeBei" + ",E=fuwei@ec.com.cn"
	    + ",OU=software center" + ",CN=root ca for fuwei";
	    
	    X509Certificate root =signCert(rootdn,rootdn,caPrivateKey,caPubKey,caPubKey,0,10);
	    writeFile("d:/root.crt",root) ;
	    
	    //generate sub 
	    String subdn = "C=cn" + ", O=newtribe" + ",L=QinHuangDao"
	    + ",ST=HeBei" + ",E=fuwei@ec.com.cn"
	    + ",OU=software center" + ",CN=newtribe";
	    X509Certificate sub =signCert(subdn,rootdn,caPrivateKey,userPubKey,caPubKey,1,10);
	    writeFile("d:/ca.crt",sub) ;
	    
	    //generate user certificate 
	    KeyPairGenerator keyPairGen=KeyPairGenerator.getInstance("RSA");
	    keyPairGen.initialize(1024);
	    KeyPair keyPair=keyPairGen.genKeyPair();
	    
	    String userdn = "C=cn" + ", O=newtribe" + ",L=QinHuangDao"
	    + ",ST=HeBei" + ",E=fuwei@ec.com.cn"
	    + ",OU=gfa" + ",CN=211.88.25.54";
	    X509Certificate user =signCert(userdn,subdn,userPrivateKey,keyPair.getPublic(),userPubKey,2,1);
	    Certificate[] certs =new Certificate[]{user,sub,root} ;
	    writeFile("d:/user.cer",user) ;
	   CertSignature.writep12("D:/apache-tomcat-6.0.16/apache-tomcat-6.0.16/conf/keystore.jks",keyPair.getPrivate(), certs) ;


	    
  }
  static BigInteger bigint =new BigInteger("100000" );
  
  
  public static X509Certificate signCert(String subjectDnString ,String issueDnString,PrivateKey signKey ,
		  PublicKey mypubKey ,PublicKey issuePubkey,int level)throws Exception {
	  return signCert(subjectDnString,issueDnString,signKey,mypubKey,issuePubkey,level,1,true);
	  
  }
  
  public static X509Certificate signCert(String subjectDnString ,String issueDnString,PrivateKey signKey ,
		  PublicKey mypubKey ,PublicKey issuePubkey,int level,int year)throws Exception {
	  return signCert(subjectDnString,issueDnString,signKey,mypubKey,issuePubkey,level,1,true);

  }
  public static X509Certificate signCert(String subjectDnString ,String issueDnString,PrivateKey signKey ,
		  PublicKey mypubKey ,PublicKey issuePubkey,int level,int year,boolean isGFA)throws Exception {
	   boolean isCA =true ;
	   
	    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

	    X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

	    X509Name subjectdn = new X509Name(subjectDnString) ;
	    certGen.setSubjectDN(subjectdn);
	    X509Name issueDn = new X509Name(issueDnString) ;
	    certGen.setIssuerDN(issueDn);
	    	    
	    
	    certGen.setNotBefore(new Date());
	    certGen.setNotAfter(new Date(System.currentTimeMillis()+year*1000*3600*24*365L));//
	    
//	    if (!isGFA){
//		    certGen.setNotBefore(new Date(System.currentTimeMillis()-3*1000*3600*24*365L));
//		    certGen.setNotAfter(new Date(System.currentTimeMillis()+7*1000*3600*24*365L));//
//	    }
	    
	    //
//	    
	 
	    bigint =(new BigInteger(String.valueOf(System.currentTimeMillis())));
	    certGen.setSerialNumber(bigint);
	    
	    certGen.setSignatureAlgorithm("SHA1withRSA");
	    certGen.setPublicKey(mypubKey);
	   
	    if (level ==2) {
	    	   BasicConstraints bc = new BasicConstraints(false);
	   	    certGen.addExtension(X509Extensions.BasicConstraints.getId(), true, bc);
	   	    
//	        GeneralName gn = new GeneralName(GeneralName.rfc822Name, new
//	                DERIA5String("testdddd@test.test"));
//	        // create a SubjectAlternativeName extension value
//	        GeneralNames  subjectAltNames = new GeneralNames(
//	                gn);
//	        certGen.addExtension(X509Extensions.SubjectAlternativeName.getId(), true, subjectAltNames);
	        
	        

	
//	        certGen.addExtension(
//	        		X509Extensions.AuthorityInfoAccess,false,
//	        		new AuthorityInformationAccess(new DERObjectIdentifier("1.3.6.1.5.5.7.48.1"),
//	        					new GeneralName(GeneralName.uniformResourceIdentifier, "http://www.gfa.com/aia/ocsp")));
	        
//	        String ocspUrl ="http://www.gfa.com/ocsp" ;
//	        GeneralName ocspLocation = new GeneralName(6, new DERIA5String(ocspUrl));
//	        certGen.addExtension(X509Extensions.AuthorityInfoAccess.getId(),
//	                             false, new AuthorityInformationAccess(X509ObjectIdentifiers.ocspAccessMethod, ocspLocation)); 
	        
	        
//	        DEREncodableVector list = new DEREncodableVector(); 
//	
//	        // AIA extension for OCSP access method. 
//	        list.add(new AccessDescription(AccessDescription.id_ad_ocsp, 
//	                                       new GeneralName(GeneralName.uniformResourceIdentifier, 
//	                                                       new DERIA5String("http://www.gfapki.com:8080/ocsp/ocsp")))); 
//	        
//	        // AIA extension for CA Issuers 
//	        list.add(new AccessDescription(AccessDescription.id_ad_caIssuers, 
//	                                       new GeneralName(GeneralName.uniformResourceIdentifier, 
//	                                                       new DERIA5String("http://211.88.9.172:8080/ope01.cer")))); 
//	
//	        
//	        certGen.addExtension(
//			X509Extensions.AuthorityInfoAccess,false,new AuthorityInformationAccess(new DERSequence(list)));     
	        
	        
	        
	        
	        DistributionPoint point[] = new DistributionPoint[1];

	        String crladdress="";
	        if (isGFA){
	        	crladdress="http://www.gfapki.com:8080/aia/cert.crl";
	        }else {
	        	crladdress="http://www.tradelink.com/service/ca.crl";

	        }

	        DistributionPointName name  =new DistributionPointName(DistributionPointName.FULL_NAME, 
	        		new GeneralName(GeneralName.uniformResourceIdentifier,crladdress));
		

	      // DistributionPointName name = new DistributionPointName(6, oct);
	       ASN1EncodableVector v = new ASN1EncodableVector();
	       
	       GeneralName gn = new GeneralName(GeneralName.registeredID, "2.3.4");
	       v.add (gn);

	       GeneralNames gns = new GeneralNames (new DERSequence(v));
	       point[0] = new DistributionPoint(name,null,null);
	       CRLDistPoint crlPoint = new CRLDistPoint(point);
	        certGen.addExtension(
			X509Extensions.CRLDistributionPoints,
			false,
			crlPoint);

	    }else if (level ==1) {
	    	
		    BasicConstraints bc = new BasicConstraints(5);
		    
		    certGen.addExtension(X509Extensions.BasicConstraints.getId(), true, bc);
		    


		    ///////////////////////
		    
		       int keyusage = X509KeyUsage.keyCertSign + X509KeyUsage.cRLSign;
		        X509KeyUsage ku = new X509KeyUsage(keyusage);
		        certGen.addExtension(X509Extensions.KeyUsage.getId(), true, ku);
		        
		        
	        DEREncodableVector list = new DEREncodableVector(); 
	        
	        String ocsp="";
	        String crosslink="";
	        if (isGFA){
	        	ocsp="http://www.gfapki.com:8080/aia/cert.crl";
	        	crosslink="http://211.88.18.145:8080/pki/gfa_cross_link.cer";
	        }else {
	        	ocsp="http://www.tradelink.com/service/ca.crl";
	        	crosslink="http://www.tradelink.com/service/parent.cer";


	        }
	    	
	        // AIA extension for OCSP access method. 
	        list.add(new AccessDescription(AccessDescription.id_ad_ocsp, 
	                                       new GeneralName(GeneralName.uniformResourceIdentifier, 
	                                                       new DERIA5String(ocsp)))); 
	        
	        // AIA extension for CA Issuers 
	        list.add(new AccessDescription(AccessDescription.id_ad_caIssuers, 
	                                       new GeneralName(GeneralName.uniformResourceIdentifier, 
	                                                       new DERIA5String(crosslink)))); 
	
	        if(isGFA)
	        certGen.addExtension(X509Extensions.AuthorityInfoAccess,false,new AuthorityInformationAccess(new DERSequence(list)));     
	    }else {//root certificate
	    	
	    BasicConstraints bc = new BasicConstraints(true);
	    certGen.addExtension(X509Extensions.BasicConstraints.getId(), true, bc);
	    
	       int keyusage = X509KeyUsage.keyCertSign + X509KeyUsage.cRLSign;
	        X509KeyUsage ku = new X509KeyUsage(keyusage);
	        certGen.addExtension(X509Extensions.KeyUsage.getId(), true, ku);
	    }
	    
	    
	    SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo((ASN1Sequence)new DERInputStream(
	            new ByteArrayInputStream(mypubKey.getEncoded())).readObject());
	            SubjectKeyIdentifier ski = new SubjectKeyIdentifier(spki);
	            
	            SubjectKeyIdentifierStructure struct =new SubjectKeyIdentifierStructure(mypubKey) ;
	     certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,struct);
	 
	     if (level !=0) {
	     SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new DERInputStream(
	             new ByteArrayInputStream(issuePubkey.getEncoded())).readObject());
	             AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki);
	     
	     certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,aki);
	     }
	     
	     
	     String policyId ="1.3.6.1.4.1.939.51" ;
	     if (!isGFA){
	    	 policyId="1.3.6.1.4.1.8420.1";
	     }
	     
	     if (policyId != null) {
	         CertificatePolicies cp = new CertificatePolicies(policyId);
	         
	         certGen.addExtension(X509Extensions.CertificatePolicies.getId(), false, cp);
	     }

	    
	     X509Certificate cert = null;
	    cert = certGen.generateX509Certificate(signKey);
	  return cert ;
  }
  
  static void writeFile(String file,X509Certificate cert) throws Exception {
	    File f = new File(file);
	 
	   // f.mkdir();
	    FileOutputStream out = new FileOutputStream(f);
	    out.write(cert.getEncoded());
	    out.close();
  }
  static void writep12(String file,PrivateKey privateKey ,Certificate[] certs ) throws Exception  {
	  KeyStore keystore = KeyStore.getInstance("jks");
	  keystore.load(null) ;
    
   
	  keystore.setKeyEntry("211.88.9.172",privateKey, "111111".toCharArray(), certs) ;
	  keystore.store(new FileOutputStream(file), "111111".toCharArray());
	  
  }

  static int serialNumber =1000 ;
  public static void signCert() throws Exception {

    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

    X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
    KeyStore keystore = KeyStore.getInstance("jks");
    InputStream in = new FileInputStream("D:/privacy/pivacy.jks");
    keystore.load(in, "111111".toCharArray());
    X509Certificate caCert = (X509Certificate)keystore.getCertificate("gfa ca certificate");

    PrivateKey caPrivateKey = (PrivateKey) keystore.getKey("root","111111".toCharArray());

    X509Certificate signCert = (X509Certificate)
        keystore.getCertificate("root");


    String issuer =signCert.getSubjectDN().toString();
    X509Name issuerdn =new X509Name(issuer) ;
    certGen.setIssuerDN(issuerdn);


    String mydn = "C=cn" + ", O=www.neuq.edu.cn" + ",L=QinHuangDao"
    + ",ST=HeBei" + ",E=gd@mail.aa.edu.cn"
    + ",OU=software center" + ",CN=newtribe";

    X509Name subjectdn = new X509Name(mydn) ;

  
    certGen.setSubjectDN(subjectdn);
    
    boolean isCA =true ;
    BasicConstraints bc = new BasicConstraints(true);
    certGen.addExtension(X509Extensions.BasicConstraints.getId(), true, bc);

    
    if (isCA) {
        int keyusage = X509KeyUsage.keyCertSign + X509KeyUsage.cRLSign;
        X509KeyUsage ku = new X509KeyUsage(keyusage);
        certGen.addExtension(X509Extensions.KeyUsage.getId(), true, ku);
    }
    
    
    
    SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo((ASN1Sequence)new DERInputStream(
            new ByteArrayInputStream(caCert.getPublicKey().getEncoded())).readObject());
            SubjectKeyIdentifier ski = new SubjectKeyIdentifier(spki);
     certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,ski);
 
     SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo((ASN1Sequence)new DERInputStream(
             new ByteArrayInputStream(signCert.getPublicKey().getEncoded())).readObject());
             AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki);
     
     certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,apki);
     
     
     String policyId ="0.3.3.3.6" ;
     if (policyId != null) {
         CertificatePolicies cp = new CertificatePolicies(policyId);
         
         certGen.addExtension(X509Extensions.CertificatePolicies.getId(), false, cp);
     }

    certGen.setNotBefore(new Date());
    certGen.setNotAfter(new Date(System.currentTimeMillis()+1000*3600*24*365L));
    String v =String.valueOf(System.currentTimeMillis());
    certGen.setSerialNumber(new BigInteger(v));
    
    certGen.setSignatureAlgorithm("SHA1withRSA");
    certGen.setPublicKey(caCert.getPublicKey());   X509Certificate cert = null;
    cert = certGen.generateX509Certificate(caPrivateKey);
    File f = new File("d:/test.cer");
    FileOutputStream out = new FileOutputStream(f);
    out.write(cert.getEncoded());

  }
  public static X509Name genX509Name() {
    Vector oids = new Vector();
    Vector attributes = new Vector();

    oids.addElement(X509Name.C);
    oids.addElement(X509Name.CN);
   oids.addElement(X509Name.E);

   // X509Name������������ɳ�,���������X509Name.C.����X509Name.ST�ȵ�,�����Ժ�����ٵ����Ӷ�Ӧ��4.


    attributes.addElement("CN");
    attributes.addElement("gfa");
        attributes.addElement("211.88.9.172@ec.com.cn");

    X509Name SubjectDN = new X509Name(oids, attributes);

    return SubjectDN ;

  }
}
